package vacuum.noxray;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public class NoXRay extends JavaPlugin{

	private Listener pl;
	private String idFile = "ids.txt";
	private String fileRepository = "http://vacuum-noxray.googlecode.com/svn/trunk/resources/";
	private boolean verbose;

	@Override
	public void onDisable() {
		pl.killThread();
		PlayerVision.revealAll(verbose);
		//TODO: give back vision
	}

	@Override
	public void onEnable() {
		PlayerVision.setPlugin(this);
		pl = new Listener();
		load();
		this.getServer().getPluginManager().registerEvents(pl, this);
	}

	public void load(){
		
		getDataFile("config.yml", true);
		
		try {
			getConfig().load(getDataFile("config.yml", false));
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (InvalidConfigurationException e1) {
			e1.printStackTrace();
		}

		boolean b = false;
		if(!getConfig().contains("objects.transparent")){
			b = true;
			getConfig().set("objects.transparent", "54, 0, 79, 20, 97, 29, 60, 44, 114, 109, 108, 67, 53, 65, 85, 107, 92, 26, 71, 64, 94, 93, 96, 66, 28, 27, 69, 70, 72, 77, 55, 75, 76, 78, 323, 51, 90, 81, 83, 59, 37, 38, 39, 40, 6, 31, 111, 8, 9");
		}

		if(!getConfig().contains("objects.hidden")){
			b = true;
			getConfig().set("objects.hidden", "54, 52, 48, 56");
		}

		if(!getConfig().contains("verbose")){
			b = true;
			getConfig().set("verbose", "false");
		}
		
		if(!getConfig().contains("search.x")){
			b = true;
			getConfig().set("search.x", 100);
		}
		
		if(!getConfig().contains("search.y")){
			b = true;
			getConfig().set("search.y", 100);
		}
		
		if(!getConfig().contains("search.z")){
			b = true;
			getConfig().set("search.z", 100);
		}
		
		if(!getConfig().contains("search.gothreadsafe")){
			b = true;
			getConfig().set("search.gothreadsafe", false);
		}
		
		if(!getConfig().contains("maxplayers")){
			b = true;
			getConfig().set("maxplayers", 5);
		}
		
		if(!getConfig().contains("objects.isactuallyopaque")){
			b = true;
			getConfig().set("objects.isactuallyopaque", false);
		}
		
		if(b)
			try {
				getConfig().save(getDataFile("config.yml", false));
			} catch (IOException e) {
				e.printStackTrace();
			}

		verbose = getConfig().getBoolean("verbose");
		
		PlayerVision.revealAll(verbose);

		String[] l = getConfig().getString("objects.hidden").replace(" ", "").split(",");
		int[] i = new int[l.length];
		StringBuffer buf = new StringBuffer();
		for (int j = 0; j < i.length; j++) {
			if(verbose)
				buf.append(l[j] + ", ");
			i[j] = Integer.parseInt(l[j]);
		}
		if(verbose){
			System.out.println(buf);
			buf.setLength(0);
		}

		String[] l2 = getConfig().getString("objects.transparent").replace(" ", "").split(",");
		int[] i2 = new int[l2.length];
		for (int j = 0; j < l2.length; j++) {
			if(verbose)
				buf.append(l2[j] + ", ");
			i2[j] = Integer.parseInt(l2[j]);
		}
		if(verbose){
			System.out.println(buf);
		}
		
		PlayerVision.setHiddenBlocks(i);
		PlayerVision.setTransparentBlocks(i2);
		
		PlayerVision.setSearchPattern(getConfig().getInt("search.x"), getConfig().getInt("search.y"), getConfig().getInt("search.z"));
		
		boolean isActuallyOpaque = getConfig().getBoolean("objects.isactuallyopaque", false);
		
		pl.setVerbose(verbose);
		pl.setIsActuallyOpaque(isActuallyOpaque);
		
		for(Player p : getServer().getOnlinePlayers()){
			if(verbose)
				System.out.println("Registering player " + p.getName());
			PlayerVision.registerPlayer(p, verbose, isActuallyOpaque);
		}
		
		PlayerVision.setThreadSafe(getConfig().getBoolean("search.gothreadsafe", false));
	}

	@Override
	public boolean onCommand(CommandSender sender, Command command,
			String label, String[] args) {
		if(command.getName().equalsIgnoreCase("noxray")){
			if(args[0].equalsIgnoreCase("reload")){
				load();
				return true;
			} else if (args[0].equalsIgnoreCase("release")){
				getServer().getPluginManager().disablePlugin(this);
				return true;
			}
		}
		return false;
	}

	public int getID(String name){
		try{
			return Integer.parseInt(name);
		} catch (NumberFormatException ex){
			//ignore
		}
		File f = getDataFile(idFile, true);
		try {
			Scanner s = new Scanner(f);
			String line;
			while(s.hasNext()){
				line = s.nextLine();
				try{
					int i = Integer.parseInt(line.substring(0, line.indexOf(' ')));
					String n = line.substring(line.indexOf(' ') + 1);
					if(n.startsWith(name)){
						return i;
					}
				} catch (Throwable t){
					//there was some funny syntax
					t.printStackTrace();
					System.err.println("[" + getDescription().getName() + "] File syntax error in id file. Skipping...");
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return -1;

	}

	public File getDataFile(String name, boolean download){
		File f = new File(getDataFolder() + File.separator + name);
		if(f.exists())
			return f;
		try {
			f.getParentFile().mkdirs();
			f.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		if(download){
			try {
				URL url = new URL(fileRepository + name);
				BufferedInputStream in = new BufferedInputStream(url.openStream());
				BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(f));
				int i;
				while((i = in.read()) != -1){
					out.write(i);
				}
				in.close();
				out.close();
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return f;
	}

}
